<?php
class Websdom_api extends CI_Model {

	
	private function call_soap($function,$parameters) {
		try	{
			$client = new SoapClient($this->config->item('websdom_url'),array('trace'=> 1));
			$response = $client->$function($parameters);
			if (strpos($response->return,'Unable To Login') > -1) {
			  show_error('Invalid Login Information. Close your browser and try to login again with a valid login details.');
			}
		}catch (Exception $e) {
			log_message('error',$e);
			show_error('THY Websdom servisine bağlanmaya çalışırken hatası oluştu. Lütfen bir süre sonra tekrar deneyiniz.');
		}
		log_message('debug',"\nDumping request:\n".$client->__getLastRequest());
		log_message('debug',$response->return);
		if ($function === 'getAvailability') { // Fix the FareInfo problem
			$replaced_response = str_replace("<FareInfo xmlns='http://temp.openuri.org/fares.xsd'>","<FareInfo>",$response->return);
			return new SimpleXMLElement($replaced_response);
		}
		return new SimpleXMLElement($response->return);
	}
	
	public function call_get_availability($username,$password,$origin,$destination,$date,$pax_count) {
		$params = array('username'=>$username,'password' => $password,'origin' => $origin,'destination' => $destination,'date' => $date);
		$response = $this->call_soap('getAvailability',$params);
			
		//load availability data from xml file
		//$xml = simplexml_load_file('availabilityresponse.xml');

		$exception = $response->xpath('//Exception');
		if (count($exception) > 0) {
			return array();
		}

		$segment_xml = $response->xpath('//SEGMENT');
		$flights_array = $this->convert_segmentsxml_to_array($segment_xml);

		$fares_xml = $response->xpath('//Fare');$tax_xml = $response->xpath('//Tax');
		$fares_array= $this->convert_faresxml_to_array($fares_xml,$tax_xml);
		$flights_with_fares = $this->find_fares($flights_array,$fares_array,$pax_count);
		return $flights_with_fares;
	}
	
	public function call_get_fares($username,$password,$segment_datas,$adult_count,$child_count,$infant_count,$overaged_count,$student_count,$military_count,$is_fare_cip) {
		$params = array('username'=>$username,
                      'password' => $password,
                      'segmentDatas' => $segment_datas,
                      'adultCount' => $adult_count,
                      'childCount' => $child_count,
                      'infantCount' => $infant_count,
                      'overagedCount' => $overaged_count,
                      'studentCount' => $student_count,
		              'militaryCount'=> $military_count,
                      'isFareCIP' => $is_fare_cip,
		);
		$response = $this->call_soap('getFares',$params);
		return $response;
	}


	public function call_create_ticket($username,$password,$segmentDatas,$passengers,$infants,$phoneNumber,$receivedField,$email,$cellphone,$receiptDatas,$remarks,$isFareCIP,$corporatePin,$needTicketPrint) {
		$params = array('username'=>$username,
                    'password' => $password,
                    'segmentDatas' => $segmentDatas,
                    'passengers' => $passengers,                  
                    'infants' => $infants,                    
                    'phoneNumber' => $phoneNumber,
                    'receivedField' => $receivedField,
                    'email' => $email,
                    'cellphone' => $cellphone,
                    'receiptDatas' => $receiptDatas,                    
                    'remarks' => $remarks,
                    'isFareCIP' => $isFareCIP,
                    'corporatePin' => $corporatePin,
                    'needTicketPrint' => $needTicketPrint);
		$response = $this->call_soap('createTicket',$params);
		return $response;
	}

	public function call_create_reservation($username,$password,$segmentDatas,$passengers,$infants,$phoneNumber,$receivedField,$email,$cellphone,$remarks) {
		$params = array('username'=>$username,
                    'password' => $password,
                    'segmentDatas' => $segmentDatas,
                    'passengers' => $passengers,                  
                    'infants' => $infants,                    
                    'phoneNumber' => $phoneNumber,
                    'receivedField' => $receivedField,
                    'email' => $email,
                    'cellphone' => $cellphone,
                    'remarks' => $remarks);
		$response = $this->call_soap('createReservation',$params);
		return $response;
	}

	public function call_get_eticket_info($username,$password,$eticketno,$surname) {
		$surname=$this->commonlibrary->to_en_upper($surname);
		$params = array('username'=>$username,
                              'password' => $password,
                              'eticketNo'=>$eticketno,
                              'surname'=>$surname);
		$response = $this->call_soap('getEticketInfo',$params);
		return $response;
	}

	public function call_put_to_pnr_queue($username,$password,$pnr) {
		// TODO: code call_put_to_pnr_queue
	}

	public function call_ticket_reservation($username,$password,$pnrNumber,$surname,$receiptDatas,$isFareCIP,$corporatePin,$needTicketPrint) {
		$params = array('username'=>$username,
                              'password' => $password,
                              'pnrNumber'=>$pnrNumber,
                              'surname'=>$surname,
                              'receiptDatas' => $receiptDatas,                    
                              'isFareCIP' => $isFareCIP,
                              'corporatePin' => $corporatePin,
                              'needTicketPrint' => $needTicketPrint);
		$response = $this->call_soap('ticketReservation',$params);
		return $response;
	}

	public function call_get_pnr($username,$password,$pnr) {
		$params=array('username'=>$username,'password' => $password,'pnrNumber' => $pnr);
		$response = $this->call_soap('getPnr',$params);
		return $response;
	}

	public function call_get_pnr_fare($username,$password,$pnr,$surname,$isFareCIP) {
		$surname=$this->commonlibrary->to_en_upper($surname);
		$params=array('username'=>$username,'password' => $password,'pnrNumber' => $pnr,'surname'=>$surname, 'isFareCIP'=>$isFareCIP);
		$response = $this->call_soap('getPnrFare',$params);
		return $response;
	}

	public function call_cancel_reservation($username,$password,$pnr) {
		$params=array('username'=>$username,'password' => $password,'pnrNumber' => $pnr);
		$response = $this->call_soap('cancelReservation',$params);
		return $response;
	}
	
	
		private function convert_faresxml_to_array($fares_xml,$tax_xml) {
		$fares = array();
		foreach ($fares_xml as $fare) {
			$key = (string)$fare->attributes()->FB.(string)$fare->attributes()->carrier.trim((string)$fare->attributes()->IND).(string)$fare->attributes()->MXD_IND;
			$fares[$key]= array('amount'=>(string)$fare->attributes()->Amount,'disc_amount'=>(string)$fare->attributes()->DiscAmount);
		}
		$fares['VQ']= (string)$tax_xml[0]->attributes()->TAX_AMOUNT;
		return $fares;
	}

	private function convert_segmentsxml_to_array($segment_xml) {
		$flights = array();
		$segment_count= count($segment_xml)-1;
		for ($i = 0; $i < $segment_count; $i++) {
			$segment= $this->get_segment_array($segment_xml[$i]);
			if ($i < $segment_count) {
				$connetion= $this->get_segment_array($segment_xml[$i+1]);
				if (strcmp($connetion['isConnectedPrevSeg'],'true')==0) {
					if ($segment['isEticket']=='E' && $connetion ['isEticket']=='E') {
						array_push($flights ,array('leg1'=>$segment,'leg2'=>$connetion));
					}
					$i++;
				}
				else {
					if ($segment['isEticket']=='E') {
						array_push($flights, array('leg1'=>$segment));
					}
				}
			}
			else {
				//for last segment push;
				if ($segment['isEticket']=='E') {
					array_push($flights,array('leg1'=>$segment));
				}
			}
		}
		return $flights;
	}

	private function get_segment_array($segment_xml) {
		$operate = 'TK';
		if (strpos($segment_xml[0]->OPERATINGAIRLINE,'ANADOLUJET IS A TRADEMARK OF TURKISH AIRLINES')>-1) {
			$operate = 'AJ';
		} 
		if (strpos($segment_xml[0]->OPERATINGAIRLINE,'ANADOLUJET IS TRADEMARK OF/THY OPERATED SUNEXPRES')>-1) {
			$operate = 'XQ';
		}
		
		//echo '<br/>OP:'.(string)$segment_xml->attributes()->flightno.':'.$segment_xml[0]->OPERATINGAIRLINE .':'. $operate;
		$cabin_based_classes = $this->find_available_cabin_based_classes($segment_xml,$operate);

		$segment_array= array ('flightno'=>(string)$segment_xml->attributes()->flightno,
                          'origin'=>(string)$segment_xml->attributes()->origin, 
                          'destination'=>(string)$segment_xml->attributes()->destination,
                   		  'departureTime'=>(string)$segment_xml->attributes()->departureTime,
                   		  'arrivalTime'=>(string)$segment_xml->attributes()->arrivalTime,
						  'crafttype'=>(string)$segment_xml->attributes()->crafttype,
						  'isEticket'=>(string)$segment_xml->attributes()->isEticket,
                          'operatingairline'=>$operate,
						  'cabin_based_classes'=>$cabin_based_classes,
                          'isConnectedPrevSeg'=>(string)$segment_xml->attributes()->isConnectedPrevSeg,
						  'nextDay'=>'',
		);
		return $segment_array;
	}
	public function find_available_cabin_based_classes($flight)
	{
		$bus_class=array();$ecr_class=array();$eco_class=array();
		foreach($flight->CLASS as $class) {
			$code=(string)$class->attributes()->code;
			$avail_seats=(string)$class->attributes()->availSeats;
			$cabin_type = $this->commonlibrary->get_cabin_type($code);
			switch ($cabin_type) {
				case 'C':
					$bus_class[$code] = array('code'=>$code,'avail_seat'=>$avail_seats);break;
				case 'Y*':
					$ecr_class[$code] = array('code'=>$code,'avail_seat'=>$avail_seats);break;
				default:
					$eco_class[$code] = array('code'=>$code,'avail_seat'=>$avail_seats);break;
			}
		}
		$available_classes=array();
		$available_classes['fare_BUS'] = $bus_class;
		$available_classes['fare_ECO'] = $eco_class;
		$available_classes['fare_ECR'] = $ecr_class;
		return $available_classes;
	}

	private function find_fares($flights,$fares,$pax_count) {
		$flights_with_fares = array();
		foreach ($flights as $flight) {
			$fwf = $this->find_best_fare($flight,$fares,$pax_count);
			$ret = $this->get_cheapest_fare($fwf,$fares);
			if (isset($ret)) {
				$fwf['fare'] = $ret;
				array_push($flights_with_fares, $fwf);
			}
		}
		return $flights_with_fares;
			
	}
	private function find_best_fare($flight,$fares,$pax_count) {
		$mxd_ind = '';
		/* useless
		if (isset($flight['leg2'])) {
			$mxd_ind = 'M';
		}
        */
		$cabin_based_classes = $flight['leg1']['cabin_based_classes'];
		foreach ($cabin_based_classes as $cabin => $classes){
			$flight['leg1']['cabin_based_fares'][$cabin] =	$this->get_best_fare_for_cabin(isset($flight['leg2']),$mxd_ind,$pax_count,$flight['leg1']['operatingairline'],$classes,$fares);
		}
		if (isset($flight['leg2']))
		{
			$carrier =$flight['leg2']['operatingairline'];
			if ($flight['leg1']['operatingairline'] == 'TK') {
				$carrier='TK'; // if first flight is TK than use TK fares for connections
			}
			$cabin_based_classes = $flight['leg2']['cabin_based_classes'];
			foreach ($cabin_based_classes as $cabin => $classes){
				$flight['leg2']['cabin_based_fares'][$cabin] =	$this->get_best_fare_for_cabin(TRUE,$mxd_ind,$pax_count,$carrier,$classes,$fares);
			}
		}
		return $flight;
	}

	public function get_best_fare_for_cabin($direct_flight,$mxd_ind,$paxCount,$carrier,$classData,$fares_array)
	{
		$best_fare = array('amount'=>999999);
		$direct_flight =  ($direct_flight)?'*':'';
		foreach($classData as $aClass)
		{
			if ($aClass['avail_seat'] >= $paxCount) {
				if ($this->is_class_airline_eligible($aClass['code'].$carrier))
				{
				  // TODO: if the fare is not available in fare array just skip it. This rule needs to be reviewed.
				  if (array_key_exists($aClass['code'].$carrier.$direct_flight.$mxd_ind, $fares_array)) {
    				  if ($fares_array[$aClass['code'].$carrier.$direct_flight.$mxd_ind]['amount'] < $best_fare['amount']){
  				        $best_fare['class']=$aClass['code'];
  				        $best_fare['amount']=$fares_array[$aClass['code'].$carrier.$direct_flight.$mxd_ind]['amount'];
     				  }
				  }
				  else {
				    log_message('error','Fare not found for: '.$aClass['code'].$direct_flight.$carrier.$mxd_ind);
				  }
				}
			}
		}
		return $best_fare;
	}

	private function get_cheapest_fare($flights,$fares) {
		$segment = $flights['leg1'];
		$next_segment = isset($flights['leg2'])?$flights['leg2']:null;

		$fare = array ('tax_YR'=>$this->commonlibrary->get_tax('YR'), 'tax_VQ' => $fares['VQ']);
		$cabin_based_fares_segment = $segment['cabin_based_fares'];
		if (isset($cabin_based_fares_segment['fare_ECR']['class'])) {
			$fare['segment']=$cabin_based_fares_segment['fare_ECR'];
			$fare['segment_cabin']='ECR';
		} elseif (isset($cabin_based_fares_segment['fare_ECO']['class'])) {
			$fare['segment']=$cabin_based_fares_segment['fare_ECO'];
			$fare['segment_cabin']='ECO';
		} elseif (isset($cabin_based_fares_segment['fare_BUS']['class'])) {
			$fare['segment']=$cabin_based_fares_segment['fare_BUS'];
			$fare['segment_cabin']='BUS';
		} else {
			return null;
		}

		if (isset($next_segment)) {
			$cabin_based_fares_connection = $next_segment['cabin_based_fares'];
			if (isset($cabin_based_fares_connection['fare_ECR']['class'])) {
				$fare['connection']=$cabin_based_fares_connection['fare_ECR'];
				$fare['connection_cabin']='ECR';
			} elseif (isset($cabin_based_fares_connection['fare_ECO']['class'])) {
				$fare['connection']=$cabin_based_fares_connection['fare_ECO'];
				$fare['connection_cabin']='ECO';
			} elseif (isset($cabin_based_fares_connection['fare_BUS']['class'])) {
				$fare['connection']=$cabin_based_fares_connection['fare_BUS'];
				$fare['connection_cabin']='BUS';
			} else {
				return null;
			}

				

			if (isset($fare['connection_cabin']))
			{
				if (!($fare['segment_cabin'] == 'ECR' && $fare['connection_cabin'] == 'ECR')) {
					$fare = array ('tax_YR'=>$this->commonlibrary->get_tax('YR'), 'tax_VQ' => $fares['VQ']);
					if (isset($cabin_based_fares_segment['fare_ECO']['class'])) {
						$fare['segment']=$cabin_based_fares_segment['fare_ECO'];
						$fare['segment_cabin']='ECO';
					} elseif (isset($cabin_based_fares_segment['fare_BUS']['class'])) {
						$fare['segment']=$cabin_based_fares_segment['fare_BUS'];
						$fare['segment_cabin']='BUS';
					}
					if (isset($cabin_based_fares_connection['fare_ECO']['class'])) {
						$fare['connection']=$cabin_based_fares_connection['fare_ECO'];
						$fare['connection_cabin']='ECO';
					} elseif (isset($cabin_based_fares_connection['fare_BUS']['class'])) {
						$fare['connection']=$cabin_based_fares_connection['fare_BUS'];
						$fare['connection_cabin']='BUS';
					}
				}
			}
		}
		return $fare;
	}



	



	/*
	 * Get ticket number for a particular passanger.
	 */
	public function get_ticket_numbers_from_pnr($pnr_view) {
		$pnr_view = (string)$pnr_view;
		$pattern = '/ S1 SSRTKNETKHK| S1 ZZRTKNETKHK/';
		preg_match_all($pattern, $pnr_view, $matches, PREG_OFFSET_CAPTURE);
		$ticket_array=array();
		for ($index = 0; $index < count($matches[0]); $index++) {
			$loc=17;
			$ticket_number = substr($pnr_view,$matches[0][$index][1]+$loc,13);
			if ($ticket_number[0]=='I') {
				$loc+=3;
				$ticket_number = substr($pnr_view,$matches[0][$index][1]+$loc,13);
			}
			$conj='';
			if (substr($pnr_view,$matches[0][$index][1]+$loc+15,1) == '/') {
				$conj= substr($pnr_view,$matches[0][$index][1]+$loc+20,3);
			}
			$ticket_array[$index]=array('ticket'=>$ticket_number,'conj'=>$conj);
		}
		return $ticket_array;
	}
	/*
	 * Get all Fares form PNR
	 */
	public function get_fare_from_pnr($pnr_view) {
		$pax_cnt=0;		
		$pnr_arr = explode(chr(10),$pnr_view);
		$fares = array();
		for ($i=0; $i < count($pnr_arr);$i++) {
			$pnr_line = $pnr_arr[$i];
			if (strpos($pnr_line,'.FARE')>0) {
			  $pax_type = trim(substr($pnr_arr[$i-1],-3));
			  $pnr_line=substr($pnr_line,strpos($pnr_line,'FARE'));

			if ($pax_type === 'NF') {
				$fares[$pax_cnt++] = array('fare'=> substr($pnr_line,8), 'tax'=> 0, 'total'=> substr($pnr_line,8)); 
			} else {		
				$fares[$pax_cnt++] = array('fare'=> substr($pnr_line,8,strpos($pnr_line,'TAX')-8),
	  			        'tax'=> substr($pnr_line,strpos($pnr_line,'TOT XT')+6,7),
		  		        'total'=> substr($pnr_line,strpos($pnr_line,'TOT TR')+8));
			  }
		  }
		}
		return $fares;
	}
	
	public function is_class_airline_eligible($class_airline) {
	   $exluded = array(
        'SAJ',   // AJ - S Class - Business Class
        'OTK',
        'UTK',   // TK - U Class - TurkTelecom Compaing Class
        'PAJ'
       );
	   if (in_array($class_airline,$exluded)) {
	     return false;
	   }
	   return true;
	   
	   
	}
}

